package com.skp.shaphan;

import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;

import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import com.skp.shaphan.layout.SQLEditorsLayout;
import com.skp.shaphan.model.ConnectionDetails;
import com.skp.shaphan.ui.CustomGlassPane;
import com.skp.shaphan.ui.SQLEditor;

/**
 * A Panel that allows the user to enter multiple SQL Statements
 * @author Stephen Phillips
 *
 */
public class SQLEditorsPane extends JScrollPane implements FocusListener, ComponentListener {
	private SQLEditor activeEditor = null;
	private ConnectionDetails connection = null;
	private SQLEditor runEditor = null;
	private SQLEditor mousedEditor = null;
	private JPanel uiView;
	private JLayeredPane viewPort;
	private int nextSQLEditorID;
	
	/**
	 * Create the interface/GUI
	 */
	public SQLEditorsPane() {
		super();
		
		// The layered pane allows us to add a glass pane in front
		viewPort = new JLayeredPane();
		viewPort.setName("sqlEditorsViewPort");
		
		// The uiView is the main panel that holds the controls the user sees
		// and interacts with
		uiView = new JPanel();
		uiView.setName("uiView");
		uiView.setLayout(new SQLEditorsLayout());

		// The custom glass pane allows us to preview all of the events first
		CustomGlassPane glassPane = new CustomGlassPane(this);
		
		// The glass pane needs to be added first so that it goes on top
		viewPort.add(glassPane, 5);
		viewPort.add(uiView, 10);
		
		// for testing you can hide one or the other
		glassPane.setVisible(true);
		uiView.setVisible(true);
		
		// this sets the Viewport of the scroll area
		this.setViewportView(viewPort);

		// for better scrolling! -- http://www.devdaily.com/blog/post/jfc-swing/how-increase-speed-jscrollpane-mouse-wheel
		this.getVerticalScrollBar().setUnitIncrement(16);
		
		uiView.setAlignmentY(0.0f);
		// I think it will be helpful to give each editor a unique name
		nextSQLEditorID = 0;

		// initialize the first editor
		this.insertSQLEditor(null);
		
		// listen for size changes so we can fix the layout
		this.addComponentListener(this);
	}

	public SQLEditor insertSQLEditor(SQLEditor insertAfterEditor) {
		SQLEditor newEditor = new SQLEditor();
		newEditor.addFocusListener(this);
		uiView.add(newEditor, insertAfterEditor);
		uiView.doLayout();
		viewPort.doLayout();
		if(activeEditor == null) {
			activeEditor = newEditor;
		}
		
		// give each editor a unique name
		newEditor.setName(Integer.toString(nextSQLEditorID));
		nextSQLEditorID++;
		
		return newEditor;
	}

	public int getRowForSQLEditor(SQLEditor editor) {
		SQLEditorsLayout layout = (SQLEditorsLayout)uiView.getLayout();
		return layout.getIndexOfComponent(editor);
	}
	
	public SQLEditor getSQLEditor(int row) {
		if(row < 0) {
			return null;
		}
		SQLEditorsLayout layout = (SQLEditorsLayout)uiView.getLayout();
		if(row >= layout.getEditorCount()) {
			return null;
		}
		SQLEditor chosenEditor = (SQLEditor)layout.getComponentAtIndex(row);
		return chosenEditor;
	}
	
	public SQLEditor getCurrentSQLEditor() {
		return activeEditor;
	}
	
	public void setConnection(ConnectionDetails connection) {
		this.connection = connection;
		ShaphanApp.getMainWindow().getToolbar().getCatalogSelector().loadCatalogs();
	}

	@Override
	public void focusGained(FocusEvent e) {
		if(e.getSource() instanceof SQLEditor) {
			activeEditor = (SQLEditor)e.getSource();
		} else if(e.getSource() instanceof JTextArea) {
			activeEditor = (SQLEditor)((JTextArea)e.getSource()).getParent();
		}
	}

	@Override
	public void focusLost(FocusEvent e) {
	}

	public ConnectionDetails getConnection() {
		return connection;
	}

	public void markAsRan(SQLEditor sqlEditor) {
		if(runEditor != null) {
			runEditor.setSqlExecuted(false);
		}
		sqlEditor.setSqlExecuted(true);
		runEditor = sqlEditor;
	}
	
	public JPanel getUIView() {
		return uiView;
	}
	
	public void setMousedEditor(SQLEditor newEditor) {
		if(newEditor == null) {
			// This means that nothing is moused over
			//   But, I don't want to show nothing moused over
			return;
		}
		if(mousedEditor != null) {
			if(mousedEditor.getName().equals(newEditor.getName())) {
				// nothing to do -- same editor
				return;
			}
			mousedEditor.setMousedOver(false);
		}
		mousedEditor = newEditor;
		if(mousedEditor != null) {
			mousedEditor.setMousedOver(true);
		}
	}

	// ---[ Component Listener ]------------------------------------------------------
	
	@Override
	public void componentHidden(ComponentEvent e) {
	}

	@Override
	public void componentMoved(ComponentEvent e) {
	}

	@Override
	public void componentResized(ComponentEvent e) {
		// The editor wasn't laying out to fill the screen when the windows was maximized
		uiView.doLayout();
	}

	@Override
	public void componentShown(ComponentEvent e) {
	}
}
